package com.wva.common.aspect;

import com.wva.common.annotation.captcha.PictureVerify;
import com.wva.common.client.CaptchaClient;
import com.wva.common.domain.dto.PictureCaptchaVerifyDTO;
import com.wva.common.enums.CaptchaType;
import com.wva.common.status.StatusEnum;
import com.wva.common.exception.BusinessException;
import com.wva.common.utils.R;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 验证码切面类：用于接口执行前校验验证码
 * 关于切面的执行顺序：
 * 日志记录>图片验证码、短信验证码>其它
 *
 * @Author: hong
 * @Date: 2025/1/14 17:23:17
 */
@Component
@Aspect
@Order(-1)
public class CaptchaVerifyAspect {
    @Autowired
    CaptchaClient captchaClient;

    @Pointcut("execution(* com.wva.*.controller.*.*(..))")
    public void pt() {}

    @Before("pt()")
    public void before(JoinPoint joinPoint) {
        // 反射获取注解 @Captcha
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        CaptchaType captchaType = null;
        boolean hasPicture = method.getAnnotation(PictureVerify.class) != null;
        if (hasPicture) captchaType = CaptchaType.PICTURE;
        if (captchaType == null) return;
        //TODO if else优化

        // 获取第一个参数（请求体对象）
        Object[] args = joinPoint.getArgs();
        if (args.length == 0 || args[0] == null) {
            //缺少请求体
            throw new BusinessException(StatusEnum.PARAMS_MISSING);
        }
        Object dto = args[0];

        // 调用验证码微服务验证验证码
        PictureCaptchaVerifyDTO pictureCaptchaVerifyDTO = new PictureCaptchaVerifyDTO();
        BeanUtils.copyProperties(dto, pictureCaptchaVerifyDTO);

        //校验验证码
        R<Object> result = captchaClient.verifyPictureCaptcha(pictureCaptchaVerifyDTO);
        if (result.getCode() != 0) {
            throw new BusinessException(result);
        }
    }
}
